<?php

declare(strict_types=1);

namespace app\admin\controller;

use think\App;
use think\facade\View;
use app\common\model\Area;
use app\common\facade\Builder;
use app\common\model\Product;
use app\common\model\User;
use app\common\model\OrderProduct;
use app\common\model\LntegralSpecItem;
use app\common\model\SpecItem;
use think\exception\ValidateException;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use app\common\tool\Result;

use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\IOFactory;

class Order extends Base
{

    //主键，默认为id
    protected string $pk = 'id';

    //主模型
    protected string $model = '\app\common\model\Order';
    protected string $refundmodel = '\app\common\model\OrderRefund';

    //关联模型
    protected array $hasOne = ['user', 'address', 'express', 'p', 'c', 'd', 't', 'commission1', 'commission2'];

    protected int $takeOver = 3;

    public function index(): string
    {
        $param = $this->request->get();
        // print('<pre>');print_r($param);die;
        $map = [];
        if (!empty($param['id'])) {
            if ($param['type'] == 1) {
                $map['commission_uid1__commission_uid2'] = $param['id'];
            } else {
                $map['uid__uid'] = $param['id'];
            }
        }
        return Builder::Table()
            ->addColumn(['type' => 'checkbox', 'fixed' => 'left', 'title' => '全选'])
            ->addColumn(['field' => 'id', 'title' => '订单ID', 'width' => 90])
            ->addColumn(['field' => 'sn', 'title' => '订单编号', 'width' => 150])
            ->addColumn(['field' => 'code', 'title' => '下单会员', 'templet' => '#_userTpl', 'width' => 250])
            ->addColumn(['field' => 'create_time', 'title' => '下单时间', 'width' => 150])
            ->addColumn(['field' => 'address', 'title' => '下单地址', 'templet' => '#addressTpl', 'width' => 250])
            ->addColumn(['field' => 'product', 'title' => '订单商品', 'templet' => '<div>{{- d.product}}</div>', 'width' => 300])

            ->addColumn(['field' => 'real_amount', 'title' => '实付金额'])
            ->addColumn(['field' => 'total_amount', 'title' => '订单金额'])

            ->addColumn(['field' => 'make', 'title' => '开票信息', 'templet' => '#_makeTpl', 'width' => 200])
            ->addColumn(['field' => 'commission', 'title' => '分销商', 'templet' => '#_commissionTpl', 'width' => 150])
            ->addColumn(['field' => 'pay_way', 'title' => '支付方式'])
            ->addColumn(['field' => 'shoptype', 'title' => '订单类型', 'templet' => '#shoptypeTpl'])
            ->addColumn(['field' => 'postage', 'title' => '运费', 'width' => 90])
            ->addColumn(['field' => 'coupon_money', 'title' => '优惠金额'])
            ->addColumn(['field' => 'fullmoney', 'title' => '满减金额'])
            ->addColumn(['field' => 'pay_time', 'title' => '支付时间', 'width' => 150])
            ->addColumn(['field' => 'post_time', 'title' => '发货时间', 'width' => 150])
            ->addColumn(['fixed' => 'right', 'align' => 'center', 'toolbar' => '#orderDemo', 'title' => '操作', 'width' => 400])
            ->addTopButtons([
                'deleteAll',
                'exportOrder' => [
                    'title' => '导出数据',
                    'url'   => url('order/exportOrder')->build(),
                    'event' => '_exportOrder'
                ],
            ])
            ->addRightButtons([
                'edit'        => ['title' => '详情', 'size' => '1920,1080'],
                'savePostage'     => ['title' => '修改运费', 'size' => '400,300', 'url' => url('Order/savePostage')->build(), 'event' => '_openNewPage'],
                'saveMoney'     => ['title' => '修改实付金额', 'size' => '400,300', 'url' => url('Order/saveMoney')->build(), 'event' => '_openNewPage'],
                'deliver'     => ['title' => '发货', 'size' => '1920,1080', 'url' => url('Order/deliver')->build(), 'event' => '_openNewPage'],
                'editAddress' => ['title' => '修改地址', 'size' => '1920,1080', 'url' => url('Order/deliver')->build(), 'event' => '_openNewPage'],
                'delete'
            ])
            ->addSearch([
                ['uid', '会员编号/昵称/手机号', 'input', '', '\app\common\model\User', 'code|nickname|mobile,id'],
                ['commission_uid1|commission_uid2', '分销商', 'input', '', '\app\common\model\User', 'code|nickname|mobile,id'],
                ['sn|receiver|receiver_tel|address_details', '订单编号|收货人|收货电话|详细地址', 'input', '', '', '', 'like'],
                ['status', '订单状态', 'select', getOrderStatus('', 2)],
                ['shoptype', '订单类型', 'select', ['shop' => '普通订单', 'seckill' => '秒杀订单', 'lntegral' => '积分订单']]
            ])
            ->addJsUrl(['order'])
            ->addSortTool([['name' => 'postage', 'pk' => $this->pk, 'url' => url('update')->build()]])
            ->addExtraHtml(['order'])
            ->addExtraMap($map)
            ->fetch('order/index');
    }

    public function edit($id = '', $tpl = 'order/edit', $info = '')
    {
        $list = $info ?: $this->model::where($this->pk, $id)->find();
        if ($list->getData('status') == 7) {
            $refundmodel = $this->refundmodel::where('order_id', $id)->find();
            if (!empty($refundmodel) && $refundmodel->status == -1) {
                $list->status = -2;
            }
        }
        //print('<pre>');print_r($list);die;
        //return parent::edit($id, $tpl, $info); // TODO: Change the autogenerated stub

        View::assign('info', $list);
        View::assign('backUrl', request()->param('back'));
        return View::fetch($tpl);
    }

    public function deliver($id = '')
    {

        if ($this->request->isPost()) {
            $param = $this->request->param();
            $info = $this->model::where('id', $param['id'])->find();
            if ($info->getData('status') > 1) {
                try {
                    $this->validate($param, 'Deliver');
                } catch (ValidateException $e) {
                    return json(['code' => -1, 'msg' => $e->getError()]);
                }
            }
            return json($this->model::deliver($param, $this->admin));
        }

        $info = $this->model::find($id);

        View::assign([
            'express' => \app\common\model\Express::where(['status' => 1, 'is_del' => 0])->select(),
            'info'    => $info
        ]);
        return View::fetch();
    }
    //修改运费
    public function savePostage($id = '')
    {

        if ($this->request->isPost()) {
            $param = $this->request->param();
            $info = $this->model::where('id', $param['id'])->find();
            return json($this->model::savePostage($param, $this->admin));
        }
        $info = $this->model::find($id);
        View::assign(['info'    => $info]);
        return View::fetch();
    }
    //修改实付金额
    public function saveMoney($id = '')
    {

        if ($this->request->isPost()) {
            $param = $this->request->param();
            $info = $this->model::where('id', $param['id'])->find();
            return json($this->model::saveMoney($param, $this->admin));
        }
        $info = $this->model::find($id);
        View::assign(['info'    => $info]);
        return View::fetch();
    }

    public function getArea($id, $level = 0)
    {
        return Area::getArea($id ?: 100000, $level);
    }
    //统计
    public function statistics()
    {
        $param = $this->request->param();
        if (!empty($param['time'])) {
            $sechtime = $param['time'];
            $times = explode(' - ', $sechtime);
            // print('<pre>');print_r($times);die;
        } else {
            $sechtime = '';
            $times[0] = date('Y-m-d', 0);
            $times[1] = date('Y-m-d', time());
        }
        if (!empty($param['keyword'])) {
            $map[] = ['title', 'like', '%' . $param['keyword'] . '%'];
            $keyword = $param['keyword'];
        } else {
            $keyword = '';
        }
        $map[] = ['is_del', '=', 0];
        $map[] = ['status', '=', 1];
        $list = Product::where($map)->field('id,title,sales')->order('sort asc')->paginate([
            'list_rows' => 10,
            'query' => request()->param()
        ]);

        foreach ($list as $k => $v) {
            $orderid = $this->model::where([['is_del', '=', 0], ['status', '>=', 2], ['status', '<=', 5]])->whereBetweenTime('create_time', $times[0], $times[1])->column('id');
            $v['rcount'] = OrderProduct::where([['pid', '=', $v['id']]])->whereIn('order_id', $orderid)->sum('num');
            $OrderProduct = OrderProduct::where([['pid', '=', $v['id']]])->whereIn('order_id', $orderid)->select();
            $money = 0;
            foreach ($OrderProduct as $kk => $vv) {
                $summoney = $vv['num'] * $vv['price'];
                $money += $summoney;
            }
            $v['money'] = $money;
            $list[$k] = $v;
        }
        View::assign('list', $list);
        View::assign('page', $list->render());
        View::assign('sechtime', $sechtime);
        View::assign('keyword', $keyword);

        return View::fetch();
    }
    /**
     * 导出订单
     */
    public function exportOrder()
    {

        ini_set('memory_limit', '1024M');
        set_time_limit(3600);

        $param = $this->request->param();
        $filed = 'id,uid,sn,receiver,coupon_money,pay_way,create_time,pay_time,total_amount,shoptype,make_type,postage,receiver_tel,fullmoney,post_time,province,city,district,town,address_details,real_amount,remark,commission_uid1,commission_uid2';
        $map[] = ['is_del', '=', 0];
        $map[] = ['id', 'in', $param['ids']];
        // /**
        //  * 时间
        //  */
        // if (isset($param['create_time']) && !empty($param['create_time'])) {
        //     $times = explode(' - ', $param['create_time']);
        //     $map[] = ['create_time', '>=', strtotime($times[0])];
        //     $map[] = ['create_time', '<=', strtotime($times[1]) + 86400];
        // }
        // /**
        //  * 订单信息
        //  */
        // if (isset($param['sn|receiver|receiver_tel|address_details']) && !empty($param['sn|receiver|receiver_tel|address_details'])) {
        //     $map[] = ['sn|receiver|receiver_tel|address_details', 'like', '%' . $param['sn|receiver|receiver_tel|address_details'] . '%'];
        // }
        // /**
        //  * 会员信息
        //  */
        // if (isset($param['uid']) && !empty($param['uid'])) {
        //     $u_user = User::where('code|nickname|mobile', $param['uid'])->value('id');
        //     $map[] = ['uid', '=', $u_user];
        // }
        // /**
        //  * 分销商信息
        //  */
        // if (isset($param['commission_uid1|commission_uid2']) && !empty($param['commission_uid1|commission_uid2'])) {
        //     $c_user = User::where('code|nickname|mobile', $param['commission_uid1|commission_uid2'])->value('id');
        //     $map[] = ['commission_uid1|commission_uid2', '=', $c_user];
        // }
        // /**
        //  * 订单状态
        //  */
        // if (isset($param['status']) && !empty($param['status'])) {
        //     $map[] = ['status', '=', $param['status']];
        // }
        // /**
        //  * 订单类型
        //  */
        // if (isset($param['shoptype']) && !empty($param['shoptype'])) {
        //     $map[] = ['shoptype', '=', $param['shoptype']];
        // }
        // print('<pre>');print_r($map);die;
        $title = '订单列表';
        $list = $this->model::where($map)
            ->field($filed)
            ->with(['p', 'c', 'd', 't', 'products', 'user', 'commission1', 'commission2'])
            ->order('id', 'desc')
            ->select();
        $calls = [
            ['call' => 'A', 'title' => '订单ID', 'width' => 10, 'marge' => true, 'field' => 'id'],
            ['call' => 'B', 'title' => '订单编号', 'width' => 40, 'marge' => true, 'field' => 'sn'],
            ['call' => 'C', 'title' => '下单会员', 'width' => 70, 'marge' => true, 'field' => 'code'],
            ['call' => 'D', 'title' => '下单时间', 'width' => 70, 'marge' => true, 'field' => 'create_time'],
            ['call' => 'E', 'title' => '收货地址', 'width' => 70, 'marge' => true, 'field' => 'address'],
            ['call' => 'F', 'title' => '收货人姓名', 'width' => 15, 'marge' => true, 'field' => 'receiver'],
            ['call' => 'G', 'title' => '收货人电话', 'width' => 20, 'marge' => true, 'field' => 'receiver_tel'],
            ['call' => 'H', 'title' => '商品名称', 'width' => 60, 'marge' => false, 'field' => 'product_title'],
            ['call' => 'I', 'title' => '商品规格', 'width' => 20, 'marge' => false, 'field' => 'spec'],
            ['call' => 'J', 'title' => '商品数量', 'width' => 13, 'marge' => false, 'field' => 'num'],
            ['call' => 'K', 'title' => '实付金额', 'width' => 13, 'marge' => true, 'field' => 'real_amount'],
            ['call' => 'L', 'title' => '订单金额', 'width' => 13, 'marge' => true, 'field' => 'total_amount'],
            ['call' => 'M', 'title' => '分销商', 'width' => 50, 'marge' => true, 'field' => 'commission'],
            ['call' => 'N', 'title' => '开票信息', 'width' => 50, 'marge' => true, 'field' => 'make'],
            ['call' => 'O', 'title' => '支付方式', 'width' => 30, 'marge' => true, 'field' => 'pay_way'],
            ['call' => 'P', 'title' => '订单类型', 'width' => 30, 'marge' => true, 'field' => 'shoptype'],
            ['call' => 'Q', 'title' => '运费', 'width' => 20, 'marge' => true, 'field' => 'postage'],
            ['call' => 'R', 'title' => '优惠金额', 'width' => 20, 'marge' => true, 'field' => 'coupon_money'],
            ['call' => 'S', 'title' => '满减金额', 'width' => 20, 'marge' => true, 'field' => 'fullmoney'],
            ['call' => 'T', 'title' => '订单备注', 'width' => 20, 'marge' => true, 'field' => 'remark'],
            ['call' => 'U', 'title' => '支付时间', 'width' => 20, 'marge' => true, 'field' => 'pay_time'],
            ['call' => 'V', 'title' => '发货时间', 'width' => 20, 'marge' => true, 'field' => 'post_time'],
        ];
        $newExcel = new Spreadsheet();

        $objSheet = $newExcel->getActiveSheet();
        $objSheet->setTitle($title)
            ->getRowDimension(1)
            ->setRowHeight(30);

        foreach ($calls as $call) {
            $objSheet->setCellValue("{$call['call']}1", $call['title']);
            $objSheet->getColumnDimension($call['call'])->setWidth($call['width']);
        }
        $baseRow = 2;
        $baseMerge = 0;
        $cell = 2;
        $end = 2;
        foreach ($list as $val) {
            $margeI = $baseMerge + $baseRow;
            $count = count($val->products);
            if ($count > 1) {
                $merge = $margeI + $count - 1;
                foreach ($calls as $call) {
                    if (!$call['marge']) continue;
                    $objSheet->mergeCells("{$call['call']}{$margeI}:{$call['call']}{$merge}");
                }
            }
            $baseMerge += $count;
            foreach ($val->products as $product) {
                foreach ($calls as $call) {
                    if ($call['marge']) continue;
                    $values = $product[$call['field']];
                    if ($call['field'] == 'spec') {
                        $spce = explode('-', $product['spec']);
                        if ($product['shoptype'] == 'lntegral') {
                            $Specname = LntegralSpecItem::whereIn('id', $spce)->column('name');
                        } else {
                            $Specname = SpecItem::whereIn('id', $spce)->column('name');
                        }
                        $values =implode('-', $Specname);
                    }
                    $objSheet->setCellValue($call['call'] . $cell, $values);
                }
                $objSheet->getRowDimension($cell)->setRowHeight(30);
                $cell += 1;
            }

            foreach ($calls as $call) {
                if (!$call['marge']) continue;
                switch ($call['field']) {
                    case 'address':
                        $value = $val->p->title . $val->c->title . $val->d->title . ($val->t ? $val->t->title : '') . $val->address_details;
                        break;
                    case 'pay_way':
                        $value = $val['pay_way'];
                        break;
                    case 'code':
                        $value = !empty($val->user) ? '会员昵称：' . ($val->user->nickname) . "\r\n" . '会员编号：' . ($val->user->code) . "\r\n" . '手机号：' . ($val->user->mobile) : "-";
                        break;
                    case 'pay_time':
                        $value = !empty($val->pay_time) ? date('Y-m-d H:i:s', intval($val->pay_time)) : '待付款';
                        break;
                    case 'pay_time':
                        $value = !empty($val->post_time) ? date('Y-m-d H:i:s', intval($val->post_time)) : '未发货';
                        break;
                    case 'commission':
                        $name = '';
                        if ($val->commission_uid1 != 0) {
                            $name .= '一级：' . $val->commission1->nickname;
                        }
                        if ($val->commission_uid2 != 0) {
                            $name .= '二级：' . $val->commission2->nickname;
                        }
                        $value = $name;
                        break;
                    case 'make':
                        $value = $val->make_type > 0 ? ('发票类型：' . $val->make_type == 1 ? '增值税普通发票' : '增值税专用发票' . "\r\n" . '开票信息：' . $val->make) : "";
                        break;
                    case 'shoptype':
                        $value = $val->shoptype == 'shop' ? '普通订单' : ($val->shoptype == 'lntegral' ? '积分订单' : '秒杀订单');
                        break;
                    default:
                        $value = $val[$call['field']];
                        break;
                }
                $objSheet->setCellValue($call['call'] . $end, $value);
            }
            $end += $count;
        }
        $end = $calls[count($calls) - 1]['call'];
        $objSheet->getStyle("A1:{$end}1")->applyFromArray([
            'font' => [
                'bold'  => true,
                'color' => [
                    'rgb' => '000000'
                ],
                'size'  => 12,
            ]
        ]);

        $line = $end . ($cell - 1);
        $objSheet->getStyle('A1:' . $line)->applyFromArray([
            'alignment' => [
                'horizontal' => Alignment::HORIZONTAL_CENTER,
                'vertical' => Alignment::VERTICAL_CENTER,
            ],
            'borders'   => [
                'outline' => [
                    'borderStyle' => Border::BORDER_THIN,
                    'color'       => ['argb' => '000000'],
                ],
                'inside'  => [
                    'borderStyle' => Border::BORDER_THIN,
                    'color'       => ['argb' => '000000'],
                ]
            ],
        ]);

        $objWriter = IOFactory::createWriter($newExcel, 'Xlsx');
        $path = '/uploads/xlsx/' . $title . date('Y-m-d_H_i_s') . '.xlsx';
        $objWriter->save(app()->getRootPath() . 'public' . $path);
        return Result::success('正在下载...', $path);
    }
}
